home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / libpcap-0.4 / inet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  6.3 KB  |  220 lines

  1. /*
  2.  * Copyright (c) 1994, 1995, 1996, 1997, 1998
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the Computer Systems
  16.  *    Engineering Group at Lawrence Berkeley Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static const char rcsid[] =
  36.     "@(#) $Header: /cvs/fragrouter/libpcap-0.4/inet.c,v 1.1.1.1 1999/05/03 04:06:43 dugsong Exp $ (LBL)";
  37. #endif
  38.  
  39. #include <sys/param.h>
  40. #include <sys/file.h>
  41. #include <sys/ioctl.h>
  42. #include <sys/socket.h>
  43. #ifdef HAVE_SYS_SOCKIO_H
  44. #include <sys/sockio.h>
  45. #endif
  46. #include <sys/time.h>                /* concession to AIX */
  47.  
  48. #if __STDC__
  49. struct mbuf;
  50. struct rtentry;
  51. #endif
  52.  
  53. #include <net/if.h>
  54. #include <netinet/in.h>
  55.  
  56. #include <ctype.h>
  57. #include <errno.h>
  58. #include <memory.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <unistd.h>
  63.  
  64. #include "pcap-int.h"
  65.  
  66. #include "gnuc.h"
  67. #ifdef HAVE_OS_PROTO_H
  68. #include "os-proto.h"
  69. #endif
  70.  
  71. /* Not all systems have IFF_LOOPBACK */
  72. #ifdef IFF_LOOPBACK
  73. #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK)
  74. #else
  75. #define ISLOOPBACK(p) ((p)->ifr_name[0] == 'l' && (p)->ifr_name[1] == 'o' && \
  76.     (isdigit((p)->ifr_name[2]) || (p)->ifr_name[2] == '\0'))
  77. #endif
  78.  
  79. /*
  80.  * Return the name of a network interface attached to the system, or NULL
  81.  * if none can be found.  The interface must be configured up; the
  82.  * lowest unit number is preferred; loopback is ignored.
  83.  */
  84. char *
  85. pcap_lookupdev(errbuf)
  86.     register char *errbuf;
  87. {
  88.     register int fd, minunit, n;
  89.     register char *cp;
  90.     register struct ifreq *ifrp, *ifend, *ifnext, *mp;
  91.     struct ifconf ifc;
  92.     struct ifreq ibuf[16], ifr;
  93.     static char device[sizeof(ifrp->ifr_name) + 1];
  94.  
  95.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  96.     if (fd < 0) {
  97.         (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
  98.         return (NULL);
  99.     }
  100.     ifc.ifc_len = sizeof ibuf;
  101.     ifc.ifc_buf = (caddr_t)ibuf;
  102.  
  103.     memset((char *)ibuf, 0, sizeof(ibuf));
  104.     if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
  105.         ifc.ifc_len < sizeof(struct ifreq)) {
  106.         (void)sprintf(errbuf, "SIOCGIFCONF: %s", pcap_strerror(errno));
  107.         (void)close(fd);
  108.         return (NULL);
  109.     }
  110.     ifrp = ibuf;
  111.     ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
  112.  
  113.     mp = NULL;
  114.     minunit = 666;
  115.     for (; ifrp < ifend; ifrp = ifnext) {
  116. #ifdef HAVE_SOCKADDR_SA_LEN
  117.         n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
  118.         if (n < sizeof(*ifrp))
  119.             ifnext = ifrp + 1;
  120.         else
  121.             ifnext = (struct ifreq *)((char *)ifrp + n);
  122.         if (ifrp->ifr_addr.sa_family != AF_INET)
  123.             continue;
  124. #else
  125.         ifnext = ifrp + 1;
  126. #endif
  127.         /*
  128.          * Need a template to preserve address info that is
  129.          * used below to locate the next entry.  (Otherwise,
  130.          * SIOCGIFFLAGS stomps over it because the requests
  131.          * are returned in a union.)
  132.          */
  133.         strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
  134.         if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
  135.             if (errno == ENXIO)
  136.                 continue;
  137.             (void)sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s",
  138.                 (int)sizeof(ifr.ifr_name), ifr.ifr_name,
  139.                 pcap_strerror(errno));
  140.             (void)close(fd);
  141.             return (NULL);
  142.         }
  143.  
  144.         /* Must be up and not the loopback */
  145.         if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr))
  146.             continue;
  147.  
  148.         for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
  149.             continue;
  150.         n = atoi(cp);
  151.         if (n < minunit) {
  152.             minunit = n;
  153.             mp = ifrp;
  154.         }
  155.     }
  156.     (void)close(fd);
  157.     if (mp == NULL) {
  158.         (void)strcpy(errbuf, "no suitable device found");
  159.         return (NULL);
  160.     }
  161.  
  162.     (void)strncpy(device, mp->ifr_name, sizeof(device) - 1);
  163.     device[sizeof(device) - 1] = '\0';
  164.     return (device);
  165. }
  166.  
  167. int
  168. pcap_lookupnet(device, netp, maskp, errbuf)
  169.     register char *device;
  170.     register bpf_u_int32 *netp, *maskp;
  171.     register char *errbuf;
  172. {
  173.     register int fd;
  174.     register struct sockaddr_in *sin;
  175.     struct ifreq ifr;
  176.  
  177.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  178.     if (fd < 0) {
  179.         (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
  180.         return (-1);
  181.     }
  182.     memset(&ifr, 0, sizeof(ifr));
  183. #ifdef linux
  184.     /* XXX Work around Linux kernel bug */
  185.     ifr.ifr_addr.sa_family = AF_INET;
  186. #endif
  187.     (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  188.     if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
  189.         (void)sprintf(errbuf, "SIOCGIFADDR: %s: %s",
  190.             device, pcap_strerror(errno));
  191.         (void)close(fd);
  192.         return (-1);
  193.     }
  194.     sin = (struct sockaddr_in *)&ifr.ifr_addr;
  195.     *netp = sin->sin_addr.s_addr;
  196.     if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
  197.         (void)sprintf(errbuf, "SIOCGIFNETMASK: %s: %s",
  198.             device, pcap_strerror(errno));
  199.         (void)close(fd);
  200.         return (-1);
  201.     }
  202.     (void)close(fd);
  203.     *maskp = sin->sin_addr.s_addr;
  204.     if (*maskp == 0) {
  205.         if (IN_CLASSA(*netp))
  206.             *maskp = IN_CLASSA_NET;
  207.         else if (IN_CLASSB(*netp))
  208.             *maskp = IN_CLASSB_NET;
  209.         else if (IN_CLASSC(*netp))
  210.             *maskp = IN_CLASSC_NET;
  211.         else {
  212.             (void)sprintf(errbuf, "inet class for 0x%x unknown",
  213.                 *netp);
  214.             return (-1);
  215.         }
  216.     }
  217.     *netp &= *maskp;
  218.     return (0);
  219. }
  220.